import org.apache.commons.io.FileUtils;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.Select;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import static java.lang.Thread.sleep;

public class Main {
    public static void main(String[] args) throws InterruptedException, IOException {
//        test_01();
//        test02();
        // 这个 test03 会报错，因为点击的是百度新闻超链接，这个链接没有放到 form 标签中
        // click 和 submit 当测试的是 form 标签中的，两者效果是一样的，没在 form 标签中是不一样的
//        test03();
//        test04();
//        test05();
//        test06();
//        Test08();
//        test08();
//        Test09();
//        page01();
//        page02();
//        page03();
//        page04();
//        page05();
//        test10();
//        test11();
        test12();
    }

    /**
     * 截图操作
     */
    private static void test12() throws InterruptedException, IOException {
        WebDriver webDriver = new ChromeDriver();
        webDriver.get("https://www.baidu.com/");
        webDriver.findElement(By.cssSelector("#kw")).sendKeys("软件测试");
        webDriver.findElement(By.cssSelector("#su")).click();
        sleep(3000);
        // 强制转换成 TakesScreenshot 类型
        File file =((TakesScreenshot)webDriver).getScreenshotAs(OutputType.FILE);
        FileUtils.copyFile(file, new File("D:\\Y\\106\\rrich\\test\\20230525jietu.png"));
    }

    /**
     * 切换窗口
     * 如果进行了跳转页面。元素会在当前 get 的页面中找元素，所以为了找到跳转到的页面中的元素，需要进行以下操作：
     */
    private static void test11() throws InterruptedException {
        WebDriver webDriver = new ChromeDriver();
        webDriver.get("https://www.baidu.com/");
        webDriver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)")).click();
        sleep(3000);
        // 通过 getWindowHandle 获取到 get 打开的页面窗口句柄
        System.out.println(webDriver.getWindowHandle());

        Set<String> handles = webDriver.getWindowHandles();;
        String target_handle = "";
        for(String handle : handles) {
            target_handle = handle;
        }
        webDriver.switchTo().window(target_handle);
        sleep(3000);

        webDriver.getWindowHandles();   // 通过 getWindowHandles 获取到所有的窗口句柄
        webDriver.findElement(By.cssSelector("#ww")).sendKeys("新闻联播");
        webDriver.findElement(By.cssSelector("#s_btn_wr")).click();
    }

    /**
     * 关闭浏览器
     */
    private static void test10() throws InterruptedException {
        WebDriver webDriver = new ChromeDriver();
        webDriver.get("https://www.baidu.com/");
        webDriver.findElement(By.cssSelector("#s-top-left > a:nth-child(1)")).click();
        sleep(3000);
//        webDriver.quit();  // quit() 关闭了整个浏览器，并且会清空缓存
        // close() 关闭了当前的页面，是 get 方法申请的是哪个页面，关闭的就是哪个页面，但不清空缓存
        webDriver.close();
    }

    /**
     * 上传文件操作：
     * 只要定位上传按钮，通过send_keys 添加本地文件路径就可以了。绝对路径和相对路径都可以，关键是上传的文件存在。
     */
    private static void page05() {
        WebDriver webDriver = new ChromeDriver();
        webDriver.get("一个 url");
        webDriver.findElement(By.cssSelector("input")).sendKeys("F:\\作业\\作业报告\\Web实验");
    }

    /**
     * 弹窗
     */
    private static void page04() throws InterruptedException {
        WebDriver webDriver = new ChromeDriver();
        webDriver.get("一个 url");
        webDriver.findElement(By.cssSelector("button")).click();
        sleep(3000);
        // alert 弹窗取消
        webDriver.switchTo().alert().dismiss();
        // 点击按钮
        webDriver.findElement(By.cssSelector("button")).click();
        // 在 alert 弹窗中输入 “哈哈”
        webDriver.switchTo().alert().sendKeys("哈哈");
        // alter 弹窗确认
        webDriver.switchTo().alert().accept();
    }

    /**
     * 下拉框处理：
     * 对于一般的元素，我们只需要一次就定位，但下拉框里的内容需
     * 要进行两次定位，先定位到下拉框对下拉框进行操作后，再定位到下拉框内里的选项。
     */
    private static void page03() {
        WebDriver webDriver = new ChromeDriver();
        webDriver.get("http://localhost:63342/_230513testcode/test03.html?_ijt=9kha9o18mbavgcq4kesab6fe3l&_ij_reload");
//        先定位到下拉框
        WebElement webElement = webDriver.findElement(By.cssSelector("#ShippingMethod"));
        Select select = new Select(webElement);
        // 通过下标进行定位
//        select.selectByIndex(3);
        // 通过元素值定位
        select.selectByValue("12.51");
    }

    /**
     * 多层框架/窗口定位
     */
    private static void page02() {
        WebDriver webDriver = new ChromeDriver();
        webDriver.get("http://localhost:63342/_230513testcode/test02.html?_ijt=fcc31r17uae7vpjq463s7c68jt&_ij_reload");
//        webDriver.switchTo().frame("f2");  // 通过frame的id或者name或者frame自带的其它属性来定位框架
        webDriver.findElement(By.cssSelector("body > div > div.span6.well > a")).click();
    }

    /**
     * 定位一组元素 ----- 定位一组对象一般用于以下场景：
     * 批量操作对象，比如将页面上所有的 checkbox 都勾上
     * 先获取一组对象，再在这组对象中过滤出需要具体定位的一些对象。比如定位出页面上所有的checkbox，然后选择最后一个
     */
    private static void page01() {
        WebDriver webDriver = new ChromeDriver();
        webDriver.get("http://localhost:63342/_230513testcode/checkbox.html?_ijt=kv95rugsioijfhjqbmsc039vdj&_ij_reload");
        // 隐式等待 3 天
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.DAYS);
        List<WebElement> webElements = webDriver.findElements(By.cssSelector("input"));
        for(int i = 0; i < webElements.size(); i++) {
            // 如果每个元素 type 值等于 CheckBox 进行点击
            // getAttribute 获取页面上的元素属性值，里面的 type 是当前的元素属性
            if(webElements.get(i).getAttribute("type").equals("checkbox")) {
                webElements.get(i).click();
            } else {
                ;      // 否则什么也不做
            }
        }
    }

    /**
     * 鼠标事件
     */
    private static void test09() throws InterruptedException {
        WebDriver webDriver = new ChromeDriver();
        // 打开百度首页
        webDriver.get("https://www.baidu.com/");
        webDriver.findElement(By.cssSelector("#kw")).sendKeys("520");
        webDriver.findElement(By.cssSelector("#su")).click();
        sleep(3000);
        // 找到图片按钮
        WebElement webElement = webDriver.findElement(By.cssSelector("#s_tab > div > a.s-tab-item.s-tab-item_1CwH-.s-tab-pic_p4Uej.s-tab-pic"));

        Actions actions = new Actions(webDriver);
        sleep(3000);
        // 鼠标右击
        actions.moveToElement(webElement).contextClick().perform();  // perform() -- 执行

    }

    /**
     * 键盘事件：
     */
    private static void test08() throws InterruptedException {
        WebDriver webDriver = new ChromeDriver();
        // 打开百度首页
        webDriver.get("https://www.baidu.com/");
        // 搜索 521
        webDriver.findElement(By.cssSelector("#kw")).sendKeys("521");
        // control + A  -- 全选（Ctrl+A）
        webDriver.findElement(By.cssSelector("#kw")).sendKeys(Keys.CONTROL, "A");
        sleep(3000);
        // control + X  -- 剪贴（Ctrl+X）
        webDriver.findElement(By.cssSelector("#kw")).sendKeys(Keys.CONTROL, "X");
        sleep(3000);
        // control + V  -- 粘贴（Ctrl+V）
        webDriver.findElement(By.cssSelector("#kw")).sendKeys(Keys.CONTROL, "V");
        sleep(3000);

    }

    /**
     * 浏览器的操作：前进和后退、控制浏览器滚动条、浏览器显示大小、以及宽高的设置
     */
    private static void test07() throws InterruptedException {
        WebDriver webDriver = new ChromeDriver();
        // 打开百度首页
        webDriver.get("https://www.baidu.com/");
        // 搜索 521
        webDriver.findElement(By.cssSelector("#kw")).sendKeys("521");
        // 强制等待 3 秒
        sleep(3000);
        webDriver.findElement(By.cssSelector("#su")).click();
        // 浏览器后退
        webDriver.navigate().back(); // navigate() -- 导航
        // 强制等待 3 秒
        sleep(3000);
        webDriver.navigate().refresh(); // 刷新
        // 浏览器前进
        sleep(3000);
        webDriver.navigate().forward();
        // 将浏览器滚动条滑到最底端
        sleep(3000);
        ((JavascriptExecutor)webDriver).executeScript("document.documentElement.scrollTop=10000");
        // 浏览器最大化显示
        webDriver.manage().window().maximize(); // window() -- 窗口
        sleep(3000);
        // 浏览器全屏显示
        webDriver.manage().window().fullscreen();
        sleep(3000);
        // 设置浏览器宽、高
        webDriver.manage().window().setSize(new Dimension(600, 1000));
    }

    /**
     * 显式等待
     */
    private static void test06() {
        // 创建驱动
        WebDriver webDriver = new ChromeDriver();
        // 打开百度首页
        webDriver.get("https://www.baidu.com/");
        // 判断元素是否可以被点击
        // 显式等待 -- 等待的是一定的条件（程序猿自己设计的）
        WebDriverWait wait = new WebDriverWait(webDriver, 3000);
//        wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#bottom_layer > div > p:nth-child(8) > span")));
        wait.until(ExpectedConditions.titleIs("百度搜索"));

    }

    /**
     * 获取当前页面的 url 和 页面标题
     */
    private static void test05() {
        ChromeOptions options = new ChromeOptions();
        // 允许所有请求，允许加载所有的页面
        options.addArguments("--remote-allow-origins=*");

        WebDriver webDriver = new ChromeDriver(options);
        // 打开百度首页
        webDriver.get("https://www.baidu.com/");

        String url = webDriver.getCurrentUrl();
        String title = webDriver.getTitle();
        if(url.equals("https://www.baidu.com/") && title.equals("百度一下，你就知道")) {
            System.out.println("当前页面 url : " + url + "，当前页面 title：" + title);
            System.out.println("测试通过");
        } else {
            System.out.println("测试不通过");
        }
    }

    /**
     * getAttribute 获取属性值
     */
    private static void test04() {
        ChromeOptions options = new ChromeOptions();
        // 允许所有请求，允许加载所有的页面
        options.addArguments("--remote-allow-origins=*");

        WebDriver webDriver = new ChromeDriver(options);
        // 打开百度首页
        webDriver.get("https://www.baidu.com/");
        String button_value = webDriver.findElement(By.cssSelector("#su")).getAttribute("value");
        if(button_value.equals("百度一下")) {
            System.out.println("测试通过");
        } else {
            System.out.println(button_value);
            System.out.println("测试不通过");
        }
    }

    private static void test03() {
        ChromeOptions options = new ChromeOptions();
        // 允许所有请求，允许加载所有的页面
        options.addArguments("--remote-allow-origins=*");

        WebDriver webDriver = new ChromeDriver(options);
        // 打开百度首页
        webDriver.get("https://www.baidu.com/");
        webDriver.findElement(By.xpath("//a[text()=\"新闻\"]")).submit(); // 此时会出错
    }

    private static void test02() throws InterruptedException {
        ChromeOptions options = new ChromeOptions();
        // 允许所有请求，允许加载所有的页面
        options.addArguments("--remote-allow-origins=*");

        WebDriver webDriver = new ChromeDriver(options);
        // 打开百度首页
        webDriver.get("https://www.baidu.com/");
        sleep(3000);

        // 找到百度搜索输入框，输入“java106“
        webDriver.findElement(By.cssSelector("#kw")).sendKeys("java106");

        // 点击了百度一下按钮
        webDriver.findElement(By.cssSelector("#su")).click();
//        webDriver.findElement(By.cssSelector("#su")).submit();

//        sleep(3000);  // 强制等待
        // 隐式等待 -- 等待的是所有的元素
        webDriver.manage().timeouts().implicitlyWait(3, TimeUnit.DAYS);

        // 清空百度搜索输入框中的数据
        webDriver.findElement(By.cssSelector("#kw")).clear();
    }

    /**
     * 元素定位、操作测试对象
     * @throws InterruptedException
     */
    public static void test01() throws InterruptedException {
        int flag = 0;
        ChromeOptions options = new ChromeOptions();
        // 允许所有请求，允许加载所有的页面
        options.addArguments("--remote-allow-origins=*");

        WebDriver webDriver = new ChromeDriver(options);
        // 打开百度首页
        webDriver.get("https://www.baidu.com");

        // 找到百度搜索输入框 --- 通过 xpath 定位元素
//        WebElement element = webDriver.findElement(By.cssSelector(".s_ipt"));
        WebElement element = webDriver.findElement(By.xpath("//*[@id=\"kw\"]"));
        // 输入软件测试
        // sendKeys -- 在对象上模拟按键输入
        element.sendKeys("软件测试");
        // 找到百度一下按钮
        // 点击 -- .click()
        webDriver.findElement(By.cssSelector("#su")).click();
        sleep(3000);
        // 校验
        // 找到搜索结果
        List<WebElement> elements = webDriver.findElements(By.cssSelector("a em"));
        for(int i = 0; i < elements.size(); i++) {
            // 如果返回的结果有测试，证明测试通过，否则测试不通过
            if(elements.get(i).getText().equals("测试")) {
                flag = 1;
                System.out.println("测试通过");
                break;
            }
        }
        if(flag == 0) {
            System.out.println("测试不通过");
        }
    }

}
